import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { BaseHttpService } from '../../../shared/services/baseHttp.service';
import { ClusterModel, ClusterModelWrapper } from './cluster.model';
import { ReplaySubject } from 'rxjs';

/**
* Research main service
*
* Author: Sorin Spiru
* Date: 13.01.2018
*/
@Injectable()
export class ClusterService extends BaseHttpService {

    public readonly ClusterMetadata: any =
        {
            X: { color: '#CCCCCC', shortName: 'Negligible' },
            A: { color: '#F9DD99', shortName: 'Low' },
            B: { color: '#F6CD66', shortName: 'Med' },
            C: { color: '#F3BC33', shortName: 'High' },
            D: { color: '#F0AB01', shortName: 'Severe' }
        };

    public readonly ExposureManagementMetadata: any =
        {
            0: { color: '#CCCCCC' },
            1: { color: '#00a19b1a' },
            2: { color: '#89D0CE' }
        };

    private companySubject = new ReplaySubject<ClusterModelWrapper[]>(1);
    public company = this.companySubject.asObservable();

    private meiSubject = new ReplaySubject<ClusterModelWrapper[]>(1);
    public mei = this.meiSubject.asObservable();

    private managementSubject = new ReplaySubject<ClusterModelWrapper[]>(1);
    public management = this.managementSubject.asObservable();

    private exposureSubject = new ReplaySubject<ClusterModelWrapper[]>(1);
    public exposure = this.exposureSubject.asObservable();

    constructor(private http: HttpClient) {
        super();
    }

    private getClusters(clusterType: string): Observable<ClusterModel[]> {
        return this.http.get<ClusterModel[]>(this.serverUrl + 'riskratingserv/api/v1/clusters/' + clusterType);
    }

    /**
    * Get the company risk clusters
    */
    public getCompanyRiskClusters(): void {
        this.getClusters('company').subscribe(data => {
            this.companySubject.next(this.prepareCluster(data));
        });
    }

    /**
    * Get the MEI risk clusters
    */
    public getMeiRiskClusters(): void {
        this.getClusters('mei').subscribe(data => {
            this.meiSubject.next(this.prepareCluster(data));
        });
    }

    public getSummaryManagementRiskClusters(): Observable<ClusterModelWrapper[]> {
        return this.getClusters('management/Overall').map(data => this.prepareCluster(data.reverse()));
    }

    public getSummaryExposureRiskClusters(): Observable<ClusterModelWrapper[]> {
        return this.getClusters('exposure/Overall').map(data => this.prepareCluster(data));
    }

    /**
    * Get the management risk clusters
    */
    public getMeiManagementRiskClusters(): void {
        this.getClusters('management/MEI').subscribe(data => {
            this.managementSubject.next(this.prepareCluster(data.reverse()));
        });
    }

    /**
    * Get the exposure risk clusters
    */
    public getMeiExposureRiskClusters(): void {
        this.getClusters('exposure/MEI').subscribe(data => {
            this.exposureSubject.next(this.prepareCluster(data));
        });
    }

    private prepareCluster(clusters: ClusterModel[]): ClusterModelWrapper[] {
        var result: ClusterModelWrapper[] = [];
        for (var i in clusters)
            result.push(new ClusterModelWrapper(
                clusters[i].assessment,
                clusters[i].code || i,
                clusters[i].name,
                this.ClusterMetadata[clusters[i].code] ? this.ClusterMetadata[clusters[i].code].shortName : clusters[i].name,
                this.ClusterMetadata[clusters[i].code] ? this.ClusterMetadata[clusters[i].code].color : '',
                clusters[i].upperBound
            ));
        return result;
    }

    private prepareExposureManagementCluster(clusters: ClusterModel[]): ClusterModelWrapper[] {
        var result: ClusterModelWrapper[] = [];
        for (var i in clusters)
            result.push(new ClusterModelWrapper(
                clusters[i].assessment,
                clusters[i].code || i,
                clusters[i].name,
                clusters[i].name,
                this.ExposureManagementMetadata[i].color,
                clusters[i].upperBound
            ));
        return result;
    }
}
